package com.goldgov.kduck;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.oauth2.core.user.DefaultOAuth2User;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
import org.springframework.util.ObjectUtils;

import javax.servlet.http.HttpServletRequest;
import java.security.Principal;
import java.util.Map;

import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.FORM_BODY_WRAPPER_FILTER_ORDER;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;

/**
 * <p>AccessUserNameFilter class.</p>
 *
 * @author guor
 * @version $Id: $Id
 */
public class AccessUserNameFilter extends ZuulFilter {
	Logger log = LoggerFactory.getLogger(AccessUserNameFilter.class);
	/** {@inheritDoc} */
	@Override
	public Object run() {
		RequestContext ctx = RequestContext.getCurrentContext();
		HttpServletRequest request = ctx.getRequest();
		Principal userPrincipal = request.getUserPrincipal();
		String sessionID=request.getSession().getId();
		if (!ObjectUtils.isEmpty(userPrincipal)) {
//			addHeaderFromJWT(ctx,userPrincipal);
			addHeader(ctx,userPrincipal);
//			OAuth2User principal = ((OAuth2AuthenticationToken) userPrincipal).getPrincipal();
//			Map<String, Object> claims = ((Jwt) ((JwtAuthenticationToken) userPrincipal).getPrincipal()).getClaims();
			//FIXME 网关获取用户信息

//			Map<String, Object> attributes = principal.getAttributes();
//			log.info("--loginID-->"+attributes.get("username")+" --name-->"+attributes.get("name")+" --userID-->"+attributes.get("userID"));
//			ctx.addZuulRequestHeader(AuthServerConstants.SESSION_KEY_USERID, (String) attributes.get("username"));
//			ctx.addZuulRequestHeader(AuthServerConstants.SESSION_KEY_USERNAME, base64Name);
//			ctx.addZuulRequestHeader(AuthServerConstants.SESSION_KEY_LOGINID, (String) attributes.get("username"));
//			ctx.addZuulRequestHeader(AuthServerConstants.SESSION_KEY_ID, sessionID);
		}
//		String userID = (String) request.getSession().getAttribute(AuthServerConstants.SESSION_KEY_USERID);
//		String name = (String) request.getSession().getAttribute(AuthServerConstants.SESSION_KEY_USERNAME);
//		String loginID = (String) request.getSession().getAttribute(AuthServerConstants.SESSION_KEY_LOGINID);
//		String departID = (String) request.getSession().getAttribute(AuthServerConstants.SESSION_KEY_DEPARTID);
//		String scopeCode = (String) request.getSession().getAttribute(AuthServerConstants.SESSION_KEY_SCOPECODE);
//		String unitScopeCode = (String) request.getSession().getAttribute(AuthServerConstants.SESSION_KEY_UNITSCOPECODE);
//		String roles = (String) request.getSession().getAttribute(AuthServerConstants.SESSION_KEY_ROLES);

//		String base64Name = "";
//		if (name != null && !"".equals(name)) {
//			base64Name = Base64.getEncoder().encodeToString(name.getBytes());
//		}
//		log.info("--loginID-->"+loginID+" --name-->"+name+" --userID-->"+userID);
//		ctx.addZuulRequestHeader(AuthServerConstants.SESSION_KEY_USERID, userID);
//		ctx.addZuulRequestHeader(AuthServerConstants.SESSION_KEY_USERNAME, base64Name);
//		ctx.addZuulRequestHeader(AuthServerConstants.SESSION_KEY_LOGINID, loginID);
//		ctx.addZuulRequestHeader(AuthServerConstants.SESSION_KEY_DEPARTID, departID);
//		ctx.addZuulRequestHeader(AuthServerConstants.SESSION_KEY_SCOPECODE, scopeCode);
//		ctx.addZuulRequestHeader(AuthServerConstants.SESSION_KEY_UNITSCOPECODE, unitScopeCode);
//		ctx.addZuulRequestHeader(AuthServerConstants.SESSION_KEY_ROLES, roles);
//		ctx.addZuulRequestHeader(AuthServerConstants.SESSION_KEY_HOST, TenancyConfiguration.getTenancy());
//		ctx.addZuulRequestHeader(AuthServerConstants.SESSION_KEY_ID, sessionID);
		return null;
	}

	private void addHeader(RequestContext ctx,Principal userPrincipal){
		Object principal1 = ((AbstractAuthenticationToken) userPrincipal).getPrincipal();
		if (principal1 instanceof Jwt){
			addHeaderFromJWT(ctx,userPrincipal);
		}else if (principal1 instanceof  DefaultOAuth2User){
			addHeaderFromOAuth2(ctx,userPrincipal);
		}
	}
	private void addHeaderFromJWT(RequestContext ctx,Principal userPrincipal){
			Map<String, Object> map = ((Jwt) ((JwtAuthenticationToken) userPrincipal).getPrincipal()).getClaims();
			log.info("--loginID-->"+map.get("user_name")+" --name-->"+map.get("name")+" --userID-->"+map.get("userID"));
			ctx.addZuulRequestHeader(AuthServerConstants.SESSION_KEY_USERID, (String) map.get("user_name"));
//			ctx.addZuulRequestHeader(AuthServerConstants.SESSION_KEY_USERNAME, base64Name);
			ctx.addZuulRequestHeader(AuthServerConstants.SESSION_KEY_LOGINID, (String) map.get("user_name"));
//			ctx.addZuulRequestHeader(AuthServerConstants.SESSION_KEY_ID, sessionID);
	}
	private void addHeaderFromOAuth2(RequestContext ctx,Principal userPrincipal){
		Map<String, Object> map = ((DefaultOAuth2User) userPrincipal).getAttributes();
		log.info("--loginID-->"+map.get("username")+" --name-->"+map.get("name")+" --userID-->"+map.get("userID"));
		ctx.addZuulRequestHeader(AuthServerConstants.SESSION_KEY_USERID, (String) map.get("username"));
//			ctx.addZuulRequestHeader(AuthServerConstants.SESSION_KEY_USERNAME, base64Name);
		ctx.addZuulRequestHeader(AuthServerConstants.SESSION_KEY_LOGINID, (String) map.get("username"));
//			ctx.addZuulRequestHeader(AuthServerConstants.SESSION_KEY_ID, sessionID);
	}

	/** {@inheritDoc} */
	@Override
	public boolean shouldFilter() {
		return true;
	}

	/** {@inheritDoc} */
	@Override
	public int filterOrder() {
		return FORM_BODY_WRAPPER_FILTER_ORDER + 2;
	}

	/** {@inheritDoc} */
	@Override
	public String filterType() {
		return PRE_TYPE;
	}

}
